﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ClassLibrary;
using System.Reflection;//引入反射命名空间


namespace _00_反射基础知识
{
    internal class Program
    {
        static void Main(string[] args)
        {
            #region 使用动态链接库添加引用的方式(没有使用反射)

            ////实例化无参构造函数
            //TEST test = new TEST();
            ////实例化有参构造函数
            //TEST test1 = new TEST("有参构造函数");
            ////调用静态方法
            //TEST.StaticMethod();
            ////调用有参静态方法
            //TEST.StaticMethod("有参静态方法");

            #endregion

            #region 使用反射的方式加载 *.dll (动态链接库) 获取类的信息 ，作为了解拓展使用


            //string DLLPath = "C:\\Users\\Administrator\\source\\repos2\\4_2_委托_事件_多线程\\ClassLibrary\\bin\\Debug\\ClassLibrary.dll";
            ////加载程序集(动态链接库)
            //Assembly assembly = Assembly.LoadFrom(DLLPath);

            //// 获取程序集中定义的所有类型
            //Type[] types = assembly.GetTypes();

            //foreach (Type type in types)
            //{
            //    Console.WriteLine($"Class: {type.Name}");            
            //    // 获取类型的所有公共方法
            //    MethodInfo[] methods = type.GetMethods();
            //    foreach (MethodInfo method in methods)
            //    {
            //        string methodInfo = String.Format(" - 方法名称: {0,-15} 方法返回值: {1}", method.Name, method.ReturnType); 
            //        Console.WriteLine(methodInfo);
            //    }
            //}

            #endregion

            Console.WriteLine("==================================反射加载DLL，方式一==================================");
            //动态链接库的路径
            string DLLPath = "C:\\Users\\Administrator\\source\\repos2\\4_2_委托_事件_多线程\\ClassLibrary\\bin\\Debug\\ClassLibrary.dll";
            //加载程序集（LoadFile：需要传入绝对路径）
            Assembly assembly = Assembly.LoadFile(DLLPath);
            //搜索程序集中的指定的类名，获取类的结构
            Type type = assembly.GetType("ClassLibrary.TEST");//Type；获取类的结构
            //创建类的实例=>实例化无参构造函数
            object obj = Activator.CreateInstance(type);
            //创建类的实例=>实例化有参构造函数
            object obj1 = Activator.CreateInstance(type,  "123");


            Console.WriteLine("==================================反射加载DLL，方式二==================================");
            string DLLPath1 = "./ClassLibrary.dll";//相对路径 即 当前EXE下相对的路径
            //加载程序集（LoadFrom：既可以传入绝对路径也可以传入相对路径）
            Assembly assembly1 = Assembly.LoadFrom(DLLPath1);
            //搜索程序集中的指定的类名，获取类的结构
            Type type1 = assembly1.GetType("ClassLibrary.TEST");//Type；获取类的结构
            //创建类的实例=>实例化无参构造函数
            object obj2 = Activator.CreateInstance(type1);
            //创建类的实例=>实例化有参构造函数
            object obj3 = Activator.CreateInstance(type1, "123");


            Console.WriteLine("==================================反射加载DLL，方式三==================================");
            string DLLPath2 = "ClassLibrary";//读取当前路径下指定的程序集名称
            //加载程序集（Load：需要传入程序集名称）
            Assembly assembly2 = Assembly.Load(DLLPath2);
            //搜索程序集中的指定的类名，获取类的结构
            Type type2 = assembly2.GetType("ClassLibrary.TEST");//Type；获取类的结构
            //创建类的实例=>实例化无参构造函数
            object obj4 = Activator.CreateInstance(type2);
            //创建类的实例=>实例化有参构造函数
            object obj5 = Activator.CreateInstance(type2, "123");

            Console.WriteLine("==================================通过反射调用静态方法==================================");
            //加载程序集（Load：需要传入程序集名称）
            Type type3 = Assembly.Load("ClassLibrary").GetType("ClassLibrary.TEST");
            //调用静态方法- 无参
            type3.InvokeMember(
                                                "StaticMethod",//搜索要调用的方法名称
                                                BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, //方法的修饰符
                                                null, //Binder：指定如何搜索方法
                                                null,//Target：指定要调用的方法的类的实例，如果是静态方法的情况下，可以传入null
                                                null//args: 方法的形参列表
                                                );
            //调用静态方法-有参
            type3.InvokeMember(
                                                "StaticMethod",//搜索要调用的方法名称
                                                BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, //方法的修饰符
                                                null, //Binder：指定如何搜索方法
                                                null,//Target：指定要调用的方法的类的实例，如果是静态方法的情况下，可以传入null
                                                new object[] { "123" }//args: 方法的形参列表
                                                );



            Console.Read();

        }
    }
}
